using Mapster;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using QiAdmin.Core;
using QiAdmin.Core.Services.Log;
using QiAdmin.Core.Services.Token;
using QiAdmin.Entity;
using QiAdmin.Model.Dtos;
using QiAdmin.Model.Dtos.Input;
using QiAdmin.Model.Dtos.Output;
using QiAdmin.Service.IService;
using QiAdmin.Repository.Repository;
using QiAdmin.Core.Models;
using ICacheService = QiAdmin.Core.Services.Cache.ICacheService;
using System.IO;
using Microsoft.AspNetCore.Components.Forms;

namespace QiAdmin.Service.Service
{
    /// <summary>
    /// TSysFiles Service
    /// </summary>
    public class TSysFilesService : BaseService<TSysFiles, TSysFiles_IN, TSysFiles_OUT>, ITSysFilesService
    {
        readonly TSysFilesRepository _tSysFilesRepository;

        public TSysFilesService(ILogService logService,
            ITokenService tokenService, ICacheService cacheService, IHttpContextAccessor httpContextAccessor, TSysFilesRepository tSysFilesRepository) : base(logService, tokenService, cacheService, httpContextAccessor.HttpContext)
        {
            _tSysFilesRepository = tSysFilesRepository;
        }

        #region 增删改查-自动生成

        /// <summary>
        /// 创建默认条件
        /// </summary>
        /// <returns></returns>
        public Expressionable<TSysFiles> CreateExp()
        {
            var exp = Expressionable.Create<TSysFiles>();
            var (dataRang, permissions) = GetUserPermission();
            switch (dataRang)
            {
                case DataRang.All:
                    break;
                case DataRang.Dept:
                    exp.And(t => t.DeptId == Token.UserDept);
                    break;
                case DataRang.DeptAndBelow:
                    exp.And(t => GetRecursiveDept().Contains(t.DeptId));
                    break;
                case DataRang.Self:
                    exp.And(t => t.SysCreateUser == Token.UserId);
                    break;
                case DataRang.Custom:
                    exp.And(t => permissions.Contains(t.DeptId));
                    break;
            }
            return exp;
        }

        /// <summary>
        /// 新增单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Add(TSysFiles_IN input)
        {
            if (input.file == null)
            {
                return CommonResult.Convert(false, "没有文件");
            }
            string filter = Path.GetExtension(input.Name);
            string name = Guid.NewGuid().ToString("N") + filter;
            string path = Path.Combine(App.StaticData.UploadPath, name);
            using var stream = new FileStream(path, FileMode.OpenOrCreate);
            input.file.CopyTo(stream);

            var model = input.Adapt<TSysFiles>();
            model.Path = path;
            int Id = _tSysFilesRepository.InsertReturnIdentity(model);
            return CommonResult.Convert(Id > 0);
        }

        /// <summary>
        /// 新增多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult AddRange(List<TSysFiles_IN> input)
        {
            var list = input.Adapt<List<TSysFiles>>();
            var result = _tSysFilesRepository.InsertRange(list);
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Edit(TSysFiles_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var model = input.Adapt<TSysFiles>();
            if (!model.IsShare)
            {
                model.SharePwd = "";
            }
            var result = _tSysFilesRepository.UpdateAndIgnore(model, exp.ToExpression());
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 获取单条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<TSysFiles_OUT> Get(TSysFiles_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);

            var result = _tSysFilesRepository.GetFirst(exp.ToExpression()).Adapt<TSysFiles_OUT>();
            return new CommonResult<TSysFiles_OUT>(result);
        }

        /// <summary>
        /// 分页获取
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<PageOutput<TSysFiles_OUT>> GetPageList(TSysFiles_IN input)
        {
            var exp = CreateExp();

            exp.AndIF(input.StartQueryTime != DateTime.MinValue, t => t.SysCreateTime >= input.StartQueryTime.Date);
            exp.AndIF(input.EndQueryTime != DateTime.MinValue, t => t.SysCreateTime < input.EndQueryTime.Date.AddDays(1));

            PageOutput<TSysFiles_OUT> pageOutput = new PageOutput<TSysFiles_OUT>();
            PageModel pageModel = new() { PageIndex = input.PageIndex, PageSize = input.PageSize };
            pageOutput.Data = _tSysFilesRepository.GetPageList(exp.ToExpression(), pageModel, t => t.Id, OrderByType.Desc).Adapt<List<TSysFiles_OUT>>();
            pageOutput.DataCount = pageModel.TotalCount;

            return new CommonResult<PageOutput<TSysFiles_OUT>>(pageOutput);
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult Remove(TSysFiles_IN input)
        {
            var exp = CreateExp();
            exp.And(t => t.Id == input.Id);
            var file = _tSysFilesRepository.GetFirst(exp.ToExpression());
            if (File.Exists(file.Path))
            {
                File.Delete(file.Path);
            }
            var result = _tSysFilesRepository.Delete(exp.ToExpression());
            return CommonResult.Convert(result);
        }

        /// <summary>
        /// 删除多条
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult RemoveRange(List<TSysFiles_IN> input)
        {
            var exp = CreateExp();
            exp.And(t => input.Select(s => s.Id).Contains(t.Id));
            var files = _tSysFilesRepository.GetList(exp.ToExpression());
            var result = _tSysFilesRepository.Delete(exp.ToExpression());
            if (result)
            {
                foreach (var file in files)
                {
                    if (File.Exists(file.Path))
                    {
                        File.Delete(file.Path);
                    }
                }
            }
            return CommonResult.Convert(result);
        }

        #endregion

        public CommonResult<string> AdminDownLoad(string fileName)
        {
            var exp = CreateExp();
            exp.And(t => t.Name == fileName);
            var file = _tSysFilesRepository.GetFirst(exp.ToExpression());
            if (file == null)
            {
                return CommonResult<string>.Convert(false, "不存在该文件");
            }
            if (!File.Exists(file.Path))
            {
                return CommonResult<string>.Convert(false, "该文件不存在");
            }
            return new CommonResult<string>(file.Path);
        }

        public CommonResult<string> ShareDownload(string fileName, string pwd)
        {
            var file = _tSysFilesRepository.GetFirst(t => t.IsShare && t.Name == fileName);
            if (file == null)
            {
                return CommonResult<string>.Convert(false, "不存在该文件");
            }
            if (file.SharePwd != pwd)
            {
                return CommonResult<string>.Convert(false, "密码错误");
            }
            if (!File.Exists(file.Path))
            {
                return CommonResult<string>.Convert(false, "该文件不存在");
            }
            return new CommonResult<string>(file.Path);
        }
    }
}
